package com.zh.risk.aop;

import com.zh.common.annotaion.CurieCache;
import com.zh.common.entity.JSONResult;
import org.apache.commons.lang3.ObjectUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * code is far away from bug with the animal protecting
 * ┏┓　　　┏┓
 * ┏┛┻━━━┛┻┓
 * ┃　　　　　　　┃
 * ┃　　　━　　　┃
 * ┃　┳┛　┗┳　┃
 * ┃　　　　　　　┃
 * ┃　　　┻　　　┃
 * ┃　　　　　　　┃
 * ┗━┓　　　┏━┛
 * 　　┃　　　┃神兽保佑
 * 　　┃　　　┃代码无BUG！
 * 　　┃　　　┗━━━┓
 * 　　┃　　　　　　　┣┓
 * 　　┃　　　　　　　┏┛
 * 　　┗┓┓┏━┳┓┏┛
 * 　　　┃┫┫　┃┫┫
 * 　　　┗┻┛　┗┻┛
 *
 * @Description: 缓存切面
 * @Author: Li.HuiNeng
 * @Create in: 2019-10-23 20:22
 * @Version: 1.0.1
 */
@Component
@Aspect
public class RedisAdvice {
    private Logger logger = LoggerFactory.getLogger(RedisAdvice.class);

    @Autowired
    private RedisTemplate redisTemplate;

    @Around("execution(* com.zh.risk.quartz..*(..))" +
            " || execution(* com.zh.risk.controller..get*(..))")
    public Object aroundMethod(ProceedingJoinPoint pjp) throws Throwable {
        MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
        Method method = methodSignature.getMethod();
        String key = null;
        String field = null;
        if (method.isAnnotationPresent(CurieCache.class)){
            logger.info("当前方法设置了CurieCache  注解");
            String target = pjp.getTarget().toString();
            StringBuilder kSb = new StringBuilder();
            kSb.append(target, target.lastIndexOf(".") + 1, target.indexOf("@"))
                    .append(":").append(method.getName());
            key = kSb.toString();
            logger.info("target is : {}, key is : {}", target, key);
            if (pjp.getArgs().length > 0 && ObjectUtils.anyNotNull(pjp.getArgs())) {
                logger.info("方法 {} 无参数", method.getName());
                StringBuilder sb = new StringBuilder();
                for (Object obj : pjp.getArgs()) {
                    sb.append(obj.toString());
                }
                field = sb.toString();
            } else {
                field = "blank";
            }
            logger.info("field is : {}", field);

            if (redisTemplate.opsForHash().hasKey(key, field)){
                logger.info("缓存里有该结果，直接从缓存里取");
                return redisTemplate.opsForHash().get(key, field);
            } else {
                logger.info("没有缓存该结果，先计算，存入缓存，再返回");
                Object result = pjp.proceed();
                redisTemplate.opsForHash().put(key, field, result);
                return result;
            }
        } else {
            logger.info("无 CurieCache  注解");
            return pjp.proceed();
        }
    }
}
